package ace.module.account.core.impl.controller.rest.admin.member;

import ace.cmp.core.model.R;
import ace.cmp.security.oauth2.resource.server.core.annotation.PreAuthorizeIsUserAuthenticated;
import ace.module.account.api.constant.AccountAuthorityConstant;
import ace.module.account.api.model.dto.IamAccountDetailDto;
import ace.module.account.api.model.input.IamAccountCommonInfoOutInput;
import ace.module.account.api.model.input.IamAccountFilterInput;
import ace.module.account.api.model.input.IamAccountModifyStatusInput;
import ace.module.account.api.model.input.register.RegisterQuickByPhoneNoOutInput;
import ace.module.account.core.impl.service.member.MemberService;
import ace.module.common.api.model.input.TenantInput;
import ace.module.common.api.model.input.TenantPageInput;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 会员账户 admin controller.
 *
 * @author Caspar
 */
@Tag(name = "会员账户-管理-API")
@PreAuthorizeIsUserAuthenticated
@AllArgsConstructor
@RestController
@RequestMapping(MemberAccountAdminController.PATH)
@Valid
public class MemberAccountAdminController {

  public static final String PATH = "/account/member";
  public static final String PATH_ADMIN_TENANT_PATH = "/admin/tenant";
  public static final String PATH_ADMIN_TENANT_SEARCH = PATH_ADMIN_TENANT_PATH + "/search";
  public static final String PATH_ADMIN_TENANT_ADD_BY_PHONE = PATH_ADMIN_TENANT_PATH + "/addByPhone";
  public static final String PATH_ADMIN_TENANT_MODIFY_COMMON_INFO = PATH_ADMIN_TENANT_PATH + "/modifyCommonInfo";
  public static final String PATH_ADMIN_TENANT_MODIFY_STATUS = PATH_ADMIN_TENANT_PATH + "/modifyStatus";
  public static final String PATH_ADMIN_TENANT_REMOVE = PATH_ADMIN_TENANT_PATH + "/remove";
  private final MemberService memberService;

  @Operation(summary = "搜索")
  @PreAuthorize("@securityService.hasAuthority('"
      + AccountAuthorityConstant.IAM_ACCOUNT_ADMIN_READ + "')")
  @PostMapping(PATH_ADMIN_TENANT_SEARCH)
  public R<Page<IamAccountDetailDto>> search(
      @Valid @NotNull @RequestBody TenantPageInput<IamAccountFilterInput> tenantPageInput) {
    Page<IamAccountDetailDto> result = memberService.adminSearch(tenantPageInput);
    return R.ok(result);
  }

  @Operation(summary = "手机号码添加账户,返回账户id")
  @PreAuthorize("@securityService.hasAuthority('"
      + AccountAuthorityConstant.IAM_ACCOUNT_ADMIN_WRITE + "')")
  @PostMapping(PATH_ADMIN_TENANT_ADD_BY_PHONE)
  public R<Long> addByPhone(
      @Valid @NotNull @RequestBody TenantInput<RegisterQuickByPhoneNoOutInput> input) {
    Long accountId = memberService.adminAddByPhone(input);
    return R.ok(accountId);
  }

  @Operation(summary = "编辑基础资料")
  @PreAuthorize("@securityService.hasAuthority('"
      + AccountAuthorityConstant.IAM_ACCOUNT_ADMIN_WRITE + "')")
  @PostMapping(PATH_ADMIN_TENANT_MODIFY_COMMON_INFO)
  public R<Void> modifyCommonInfo(
      @Valid @NotNull @RequestBody IamAccountCommonInfoOutInput input) {
    memberService.adminModifyCommonInfo(input);
    return R.ok();
  }

  @Operation(summary = "修改状态")
  @PreAuthorize("@securityService.hasAuthority('"
      + AccountAuthorityConstant.IAM_ACCOUNT_ADMIN_WRITE + "')")
  @PostMapping(PATH_ADMIN_TENANT_MODIFY_STATUS)
  public R<Void> modifyStatus(
      @Valid @NotNull @RequestBody IamAccountModifyStatusInput input) {
    memberService.adminModifyStatus(input);
    return R.ok();
  }

  @Operation(summary = "删除", parameters = {
      @Parameter(name = "[]", description = "账户id")
  })
  @PreAuthorize("@securityService.hasAuthority('"
      + AccountAuthorityConstant.IAM_ACCOUNT_MEMBER_REMOVE + "')")
  @PostMapping(PATH_ADMIN_TENANT_REMOVE)
  public R<Void> remove(
      @Valid @NotNull @RequestBody List<Long> accountIds) {
    memberService.adminRemove(accountIds);
    return R.ok();
  }
}
